﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using Barbar.MapReport.DataSource.Resources;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;
using Barbar.MapReport.DataSource.Entities;

namespace Barbar.MapReport.DataSource {
  internal class RegionGeometryProviderDB : RegionGeometryProvider {
    private string m_ConnectionStringName;

    public override void Initialize(string name, NameValueCollection config) {
      base.Initialize(name, config);

      if (config == null)
        throw new ArgumentNullException("config");

      m_ConnectionStringName = config["connectionStringName"];
      if (String.IsNullOrEmpty(m_ConnectionStringName))
        throw new DataSourceException(Translator.Error_ConnectionStringNameNotSpecified);
    }

    public override bool ContainsRegionGeometry(string regionId, ZoomLevel zoomLevel) {
      bool result;
      using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[m_ConnectionStringName].ConnectionString)) {
        SqlCommand cmd = new SqlCommand("ContainsRegionGeometry", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@RegionId", SqlDbType.VarChar, 10).Value = regionId;
        cmd.Parameters.Add("@ZoomLevelId", SqlDbType.Int).Value = zoomLevel.Id;
        
        SqlParameter paramResult = new SqlParameter("@Result", SqlDbType.Int);
        paramResult.Direction = ParameterDirection.Output;
        cmd.Parameters.Add(paramResult);

        conn.Open();
        cmd.ExecuteNonQuery();
        result = ((int)paramResult.Value) == 1;
        conn.Close();
      }
      return result;
    }

    public override Polygon GetRegionGeometry(string regionId, ZoomLevel zoomLevel) {
      RawPolygon result = new RawPolygon();
      using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[m_ConnectionStringName].ConnectionString)) {
        SqlCommand cmd = new SqlCommand("GetRegionGeometry", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@RegionId", SqlDbType.VarChar, 10).Value = regionId;
        cmd.Parameters.Add("@ZoomLevelId", SqlDbType.Int).Value = zoomLevel.Id;

        conn.Open();
        using (SqlDataReader reader = cmd.ExecuteReader()) {
          while (reader.Read()) {
            int polylineIndex = reader.GetInt32(reader.GetOrdinal("PolylineIndex"));
            decimal latitude = reader.GetDecimal(reader.GetOrdinal("Latitude"));
            decimal longitude = reader.GetDecimal(reader.GetOrdinal("Longitude"));

            if (result.Count <= polylineIndex)
              result.Add(new RawPolyline());

            RawPolyline polyline = result[polylineIndex];
            polyline.Add(new Point(latitude, longitude));
          }
        }
        conn.Close();
      }
      return result.ToPolygon();
    }
  }
}
